package com.leo.base_project.Utils;


import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class LogUtils {

    // 文件后缀名
    private static final String SUFFIX = ".java";  // .kt
    private static final int V = 0x1;
    private static final int D = 0x2;
    private static final int I = 0x3;
    private static final int W = 0x4;
    private static final int E = 0x5;
    private static final int A = 0x6;
    private static final int JSON = 0x7;
    private static final int JSON_INDENT = 4;
    // 栈信息，获取当前栈的信息
    private static final int STACK_TRACE_INDEX = 3;
    // 默认的空字符串打印内容
    private static final String NULL_MSG = "Log with null object";
    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    // 是否打印输出log
    private static boolean IS_SHOW_LOG = true;
    // TAG默认设置值
    private static String TAG = "LOG_TAG";

    /**
     * 设置是否显示log
     *
     * @param SHOW_LOG String
     */
    public static void showLog(boolean SHOW_LOG) {
        IS_SHOW_LOG = SHOW_LOG;
    }

    /**
     * Log V级别
     *
     * @param logMsg String
     */
    public static void v(String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(V, null, logMsg);
        }
    }

    /**
     * Log V级别 可设置Tag
     * @param Tag    String
     * @param logMsg String
     */
    public static void v(String Tag, String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(V, Tag, logMsg);
        }
    }

    /**
     * Log D级别
     *
     * @param logMsg String
     */
    public static void d(String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(D, null, logMsg);
        }
    }

    /**
     * Log D级别 可设置Tag
     *
     * @param Tag    String
     * @param logMsg String
     */
    public static void d(String Tag, String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(D, Tag, logMsg);
        }
    }

    /**
     * Log I级别
     *
     * @param logMsg String
     */
    public static void i(String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(I, null, logMsg);
        }
    }

    /**
     * Log I级别 可设置Tag
     *
     * @param Tag    String
     * @param logMsg String
     */
    public static void i(String Tag, String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(I, Tag, logMsg);
        }
    }

    /**
     * Log W级别
     *
     * @param logMsg String
     */
    public static void w(String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(W, null, logMsg);
        }
    }

    /**
     * Log W级别 可设置Tag
     *
     * @param Tag    String
     * @param logMsg String
     */
    public static void w(String Tag, String logMsg) {
        if (IS_SHOW_LOG) {
            printLog(W, Tag, logMsg);
        }
    }

    /**
     * Log E级别
     *
     * @param errorMsg String
     */
    public static void e(String errorMsg) {
        if (IS_SHOW_LOG) {
            printLog(E, null, errorMsg);
        }
    }

    /**
     * Log E级别 可设置Tag
     *
     * @param Tag      String
     * @param errorMsg String
     */
    public static void e(String Tag, String errorMsg) {
        if (IS_SHOW_LOG) {
            printLog(E, Tag, errorMsg);

        }
    }

    /**
     * 格式化打印json
     *
     * @param jsonStr String
     */
    public static void json(String jsonStr) {
        if (IS_SHOW_LOG) {
            printLog(JSON, null, jsonStr);
        }
    }

    /**
     * 格式化打印json，可以设置Tag
     *
     * @param Tag     String
     * @param jsonStr String
     */
    public static void json(String Tag, String jsonStr) {
        if (IS_SHOW_LOG) {
            printLog(JSON, Tag, jsonStr);

        }
    }

    /**
     * 获取超链接内容，TAG，打印内容，头部显示信息
     *
     * @param tagStr String
     * @param obj    String
     * @return String[]
     */
    private static String[] wrapperContent(String tagStr, String obj) {

        //获取栈信息
        StackTraceElement[] sElements = new Throwable().getStackTrace();
        StackTraceElement targetElement = sElements[STACK_TRACE_INDEX];

        //完整路径类名：com.frame.android.MainActivity.java
        String className = targetElement.getClassName();

        String[] classNameInfo = className.split("\\.");

        //获取文件名MainActivity.java 未适配.kt文件
        if (classNameInfo.length > 0) {
            className = classNameInfo[classNameInfo.length - 1];
            if (className.contains("$")) {
                int position = className.indexOf("$");
                className = className.substring(0, position) + SUFFIX;
            } else {
                className = className + SUFFIX;
            }
        }

        //当前方法名称
        String methodName = targetElement.getMethodName();

        //当前所在行数
        int lineNumber = targetElement.getLineNumber();

        if (lineNumber < 0) {
            lineNumber = 0;
        }

        //将当前方法名的第一个字母改成大写并返回完整方法名00
        String methodNameShort = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);

        //获取Tag ,没有设置Tag则使用默认的Tag
        String tag = (tagStr == null ? TAG : tagStr);

        //设置打印内容，若为空则显示默认的打印内容
        String msg = (obj == null) ? NULL_MSG : obj;

        //设置超链接
        String headString = "[ (" + className + ":" + lineNumber + ") # " + methodNameShort + " ] ";

        return new String[]{tag, msg, headString};

    }

    /**
     * 打印日志
     *
     * @param type   int
     * @param Tag    String
     * @param logMsg String
     */
    private static void printLog(int type, String Tag, String logMsg) {

        String[] contents = wrapperContent(Tag, logMsg);
        String tag = contents[0];
        String msg = contents[1];
        String headString = contents[2];

        switch (type) {
            //打印基本的log信息
            case V:
            case D:
            case I:
            case W:
            case E:
            case A:
                printDefaultLog(type, tag, headString + msg);
                break;
            //打印json格式化数据
            case JSON:
                printJsonLog(tag, msg, headString);
                break;

        }

    }

    /**
     * 调用系统api，打印log
     *
     * @param type   int
     * @param tag    String
     * @param logMsg String
     */
    private static void printDefaultLog(int type, String tag, String logMsg) {
        switch (type) {
            case V:
                Log.v(tag, logMsg);
                break;
            case D:
                Log.d(tag, logMsg);
                break;
            case I:
                Log.i(tag, logMsg);
                break;
            case W:
                Log.w(tag, logMsg);
                break;
            case E:
                Log.e(tag, logMsg);
                break;
            case A:
                Log.wtf(tag, logMsg);
                break;
        }

    }

    /**
     * 打印格式化json字符串
     *
     * @param tag        String
     * @param msg        String
     * @param headString String
     */
    private static void printJsonLog(String tag, String msg, String headString) {
        String message;
        try {
            if (msg.startsWith("{")) {
                JSONObject jsonObject = new JSONObject(msg);
                message = jsonObject.toString(JSON_INDENT);
            } else if (msg.startsWith("[")) {
                JSONArray jsonArray = new JSONArray(msg);
                message = jsonArray.toString(JSON_INDENT);
            } else {
                message = msg;
            }
        } catch (JSONException e) {
            message = msg;
        }

        printLine(tag, true);
        message = headString + LINE_SEPARATOR + message;
        String[] lines = message.split(LINE_SEPARATOR);
        for (String line : lines) {
            Log.i(tag, "║ " + line);
        }
        printLine(tag, false);
    }

    private static void printLine(String tag, boolean isTop) {
        if (isTop) {
            Log.i(tag, "╔═════════════════════════════════════════════════");
        } else {
            Log.i(tag, "╚═════════════════════════════════════════════════");
        }
    }

}
